/*
 * UnitDirector.cpp
 *
 *  Created on: Nov 3, 2008
 *      Author: Ryan
 */

#include "UnitDirector.h"

#include "../OOInterface/Objects/Units/UnitBuilder.h"
#include "SpringAIInterface.h"
#include "../OOInterface/Objects/Logger.h"

#include "../rts/Sim/MoveTypes/MoveInfo.h"

UnitDirector::UnitDirector( SpringAIInterface* i ) :
	_i(i)
{
}

UnitDirector::~UnitDirector()
{
}

void UnitDirector::build( const UnitDef* def, OOInterface::UnitBuilder& builder, OOInterface::UnitSet prototypes )
{
	builder
		.addBuildTime( def->buildTime)
		.addMaxHealth( def->health)
		.addName( def->name)
		.addSize( def->xsize, def->ysize )
		.addID( def->id );

	const OOInterface::ResourceList& list = _i->getResourceTypes();

	//TODO: THIS IS BAD, connascence of position between this class and SpringAIInterface
	//Changing the ordering in the original list = DOOOOOM.
	const OOInterface::Resource& metal = list.at(0);
	const OOInterface::Resource& energy = list.at(1);

	builder
		.addResourceCost( energy, def->energyCost )
		.addResourceCost( metal, def->metalCost )
		.addResourceStorage( energy, def->energyStorage )
		.addResourceStorage( metal, def->metalStorage )
		.addResourceUpkeep( energy, def->energyUpkeep )
		.addResourceUpkeep( metal, def->metalUpkeep );

	if( def->extractRange > 0.0f )
		builder.addResourceExtractorAspect( metal, def->extractRange /8.0f ); // Must convert from Spring units to GameMap units

	float energyGenerated = 0.0f;
	if( def->tidalGenerator > 0.0f )
		energyGenerated += _i->getGameMap().getTidalStrength();
	if( def->windGenerator > 0.0f )
		energyGenerated += (_i->getGameMap().getMaxWindSpeed() - _i->getGameMap().getMinWindSpeed()) /2.0f;
	if( def->energyMake > 0.0f )
		energyGenerated += def->energyMake;

	if( energyGenerated > 0.0f )
		builder.addResourceGeneration( energy, energyGenerated );

	if( def->metalMake > 0.0f )
		builder.addResourceGeneration( metal, def->metalMake );


	//if( def->isFeature )
		// reclaimable?

	if( def->builder ) {
		OOInterface::ConstUnitSet buildSet;

		for( std::map<int, std::string>::const_iterator it = def->buildOptions.begin(); it != def->buildOptions.end(); ++it )
			for( OOInterface::UnitSet::const_iterator u = prototypes.begin(); u != prototypes.end(); ++u )
				if( (*it).second.compare( (*u)->getName() ) == 0)
					buildSet.insert( *u );

		builder.addBuilderAspect( buildSet, def->buildDistance, def->repairSpeed, def->buildSpeed, def->captureSpeed, def->reclaimSpeed );
	}

	if( def->transportCapacity > 0)
		builder.addTransportAspect();

	if( def->movedata || def->canfly )
	{
		if( def->movedata )
		{
			if( def->movedata->moveType == MoveData::Ship_Move )
				builder.addWaterAspect();
			else if( def->movedata->moveType == MoveData::Ground_Move )
				builder.addLandAspect();
			else if( def->movedata->moveType == MoveData::Hover_Move )
			{
				builder.addWaterAspect();
				builder.addLandAspect();
			}

		}
		else if( def->canfly )
		{
			builder.addAirAspect(0.0f, 0.0f);
		}


		if( !def->cantBeTransported )
			builder.addTransportability();
	}
	else
	{
		//If it made it this far it cant move == building
		builder.addBuildingAspect( -1.0f *def->minWaterDepth, -1.0f *def->maxWaterDepth, def->maxHeightDif );

		//Still want to add land/water/air aspects tho to represent buildings that can be in the air/water/land
	}





}
